#include "Common.hlsl"

float LinearRoughness;
float3 Reflectance;
float3 DiffuseColor;

samplerCUBE MapSpecularLD;
float4		MapSpecularLD_TexelSize;
samplerCUBE MapDiffuseLD;
sampler2D	MapDFG;

struct VS_IN {
	float4 position:POSITION;
	float3 normal:NORMAL;
};

struct FS_IN {
	float4 p:SV_POSITION;
	float3 position:TEXCOORD0;
	float3 normal:TEXCOORD1;
};

#define VS_OUT FS_IN

VS_OUT vert(VS_IN input) {
	VS_OUT o = (VS_OUT)0; 
	o.p = UnityObjectToClipPos(input.position); 
	o.position = mul(unity_ObjectToWorld, input.position).xyz; 
	o.normal = mul(unity_ObjectToWorld, float4(input.normal, 0)).xyz; 
	return o; 
}

float4 frag(FS_IN input) : SV_TARGET0 {
	float3 N = normalize(input.normal);
	float3 V = normalize(_WorldSpaceCameraPos - input.position);
	float NdotV = saturate(dot(N, V));
	float3 L = reflect(-V, N);
	float2 size = MapSpecularLD_TexelSize.zw;
	uint nXMipLevels = (uint)(floor(log2(size.x)) + 1);
	uint nYMipLevels = (uint)(floor(log2(size.y)) + 1);
	uint nMipLevels = max(nXMipLevels, nYMipLevels);
	float roughness = LinearRoughness * LinearRoughness;
	float mipLevel = Roughness2MipLevel(roughness, nMipLevels);
	float3 specularLD = texCUBElod(MapSpecularLD, float4(L, mipLevel));
	float3 diffuseLD = texCUBE(MapDiffuseLD, N);
	float3 f0 = 0.6 * pow(Reflectance, 2);
	float3 DFG = tex2D(MapDFG, float2(NdotV, roughness));
	float3 specularColor = (f0 * DFG.x + DFG.y) * specularLD;
	float3 diffuseColor = DFG.z * diffuseLD * DiffuseColor;
	return float4(specularColor + diffuseColor, 1);
}